package com.example.demo.config;

import feign.Feign;
import feign.RequestInterceptor;
import feign.RequestTemplate;
import org.springframework.boot.web.servlet.error.DefaultErrorAttributes;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Primary;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.util.Enumeration;

/**
 * @author ChoviWu
 * @date 2018/12/7
 * Description :
 */
public class FeignConfig {

    /**
     * 自定义错误解码器
     */
    @Bean
    @Primary
    public Feign.Builder myFeign() {
        return Feign.builder().errorDecoder(new MyErrorDecoder());
    }

    /**
     * 添加request请求的header
     */
    @Bean
    public RequestInterceptor feignInterceptor() {
        return new FeignInterception();
    }

    /**
     * 覆盖spring默认的响应消息格式
     */
    @Bean
    public DefaultErrorAttributes defaultRosesErrorAttributes() {
        return new MyErrorAttributes();
    }


    class FeignInterception  implements RequestInterceptor{
        @Override
        public void apply(RequestTemplate template) {
            HttpServletRequest request = null;
            //当前feign远程调用环境不是由http接口发起，例如test单元测试中的feign调用或者项目启动后的feign调用
            try {
                request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
                request = new HttpServletRequestWrapper(request);
            } catch (NullPointerException e) {
                //被调环境中不存在request对象，则不往header里添加当前请求环境的header
                return;
            }
            Enumeration<String> elements = request.getHeaderNames();
            if (elements != null) {
                while (elements.hasMoreElements()) {
                    String name = elements.nextElement();
                    String value = request.getHeader(name);
                    //添加header
                    template.header(name, value);
                }
            }
        }
    }

}
